package edu.lnu.project.timeeditapp.adapter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TreeSet;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService.RemoteViewsFactory;
import android.widget.Toast;
import com.lnu.project.timeeditapp.R;
import edu.lnu.project.timeeditapp.db.TimeEditDataSource;
import edu.lnu.project.timeeditapp.helper.MyHelper;
import edu.lnu.project.timeeditapp.parser.Event;
import edu.lnu.project.timeeditapp.widget.WeekWidgetProvider;


/**
 * If you are familiar with Adapter of ListView,this is the same as adapter
 * with few changes
 * 
 */
public class MyWidgetListViewAdapter implements RemoteViewsFactory {

	private static final int TYPE_EVENT = 0;
    private static final int TYPE_DAY = 1;
    private static final int TYPE_MAX_COUNT = TYPE_DAY + 1;
    
    private ArrayList<Event> mData = new ArrayList<Event>();
    private TreeSet<Integer> mDaysSet = new TreeSet<Integer>();
    
    private TimeEditDataSource datasource;

    private Context context;

    public MyWidgetListViewAdapter(Context context, Intent intent) {
    	this.context = context; 	
    	
		//Create new database connection
		datasource = new TimeEditDataSource(context);
        
		//Try to populate the list with the remaining events
        try{
        	populateList( getWeekRemainingEvents( MyHelper.getCurrentWeek(), 0 ) );
        } catch ( Exception e ){
        	System.out.println("Error could not populate widget: "+e);
        }
    }
        
    /**
     * Removes all event that are in the past and returns a list with only the remaining ones
     * @param ArrayList<Event>
     * @return ArrayList<Event> no events from the past
     * @throws ParseException
     */
    private ArrayList<Event> removePastEvents(ArrayList<Event> events) throws ParseException{
    	
    	//Create new list that will contain remaining events
    	ArrayList<Event> remainingEvents = new ArrayList<Event>();
    	
    	Date todayDateNowTime = new Date();
    	for(Event event : events){
    		String eventDayAndTime = event.getBeginDate()+" "+event.getEndTime();
    		
    		Date eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(eventDayAndTime);
    		
    		if( !( eventDate.before(todayDateNowTime) ) ) { 
    			remainingEvents.add(event);
    		}
    	}
    	return remainingEvents;
    }

    
    /**
     * Get the remaining events for a specific week
     * @param int (the specific week)
     * @return ArrayList<Event> remaining events
     */
	private ArrayList<Event> getWeekRemainingEvents(int week, int c){
		int counter = c;
		if( counter < 5 ){
			int nextWeek = MyHelper.changeWeek(week, 1);
			
			//Get week events from the database
			datasource.open();
			ArrayList<Event> events = datasource.getWeekEvents(week);
			datasource.close();
			
			//Get weeks remaining event
			ArrayList<Event> remainingEvents = null;
			try{
				remainingEvents = removePastEvents(events); // TODO Add this functionality to the database
			} catch ( ParseException pe ){
				Toast.makeText(context, "Error was unable to remove past events", Toast.LENGTH_SHORT).show();
			}
			
			//If there is no remaining events get next weeks event
			if( remainingEvents == null || remainingEvents.size() == 0 ){
				System.out.println(" There are no remaining events");
				
				Toast.makeText(context, "You had no more appointments this week ("+week+") so next week is shown ("+nextWeek+")", Toast.LENGTH_SHORT).show();
				
				//Get next weeks event
				counter++;
				getWeekRemainingEvents( nextWeek, counter ); 
			} 
			else {
				System.out.println("There are some remaining events");
				
				//Create a remoteView with the widget layout
				RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.timeeditwidgetweek);
				
				//Show the correct week
				remoteViews.setTextViewText(R.id.textWeekWeekWidgetView, "Week "+week);
				
				//Push an update of the widget to display the data added in the remoteview
				WeekWidgetProvider.pushWidgetUpdate(context, remoteViews);
	
			}
			
			System.out.println("Return remaining events");
			return remainingEvents;
		}
		return new ArrayList<Event>();
	}
	
	/**
	 * Populate the list with events
	 * @param ArrayList<Event>
	 */
	private void populateList(ArrayList<Event> events){
		
		Boolean isFirstDay = true;
		int countEvents = 0;
		String previousDay = "";
		
		//While there still are events in the list
    	while(countEvents < events.size()){
    		
    		// First we always print the day
    		if(isFirstDay){	
    			
    			// Get the day
    			previousDay = events.get(0).getBeginDate(); 
    			
    			// Use first event to be able to find right day
    			addDayItem(events.get(0)); 
    			
    			//No more events can be firstDay
    			isFirstDay = false;
    		} 
    		// Check so its not a new day
    		else if( events.get(countEvents).getBeginDate().contains(previousDay) ){ 
    			//Add event item
    			addEventItem(events.get(countEvents));
    			
    			//Go to next event
    			countEvents++;
    		}
    		// When its a new day add a new day seperator
    		else{ 
    			//Add new day item
    			addDayItem(events.get(countEvents));
    			
    			//Set previous day to this day
    			previousDay = events.get(countEvents).getBeginDate();
    			
    		}
    	}
	}
	
	/**
     * Adds list item that specifies which event it is
     * @param event
     */
    public void addEventItem(final Event event) {
        mData.add(event);
    }

    /**
     * Adds list item that specifies which day it is
     * @param event
     */
    public void addDayItem(final Event event) {
        mData.add(event);
        // save day position
        mDaysSet.add(mData.size() - 1);
    }
    /*
     *Similar to getView of Adapter where instead of View we return RemoteViews 
     */
    @Override
    public RemoteViews getViewAt(int position) {
    	Event event = mData.get(position);
    	int type = getItemViewType(position);
    	RemoteViews remoteView;
    	
    	switch (type) {
    	case TYPE_EVENT:
    		
    		//Create a new remoteView with the correct layout
    		remoteView = new RemoteViews( context.getPackageName(), R.layout.listview_item_event);
        	
    		//Fill the remoteView with data
    		remoteView.setTextViewText(R.id.textViewListViewItem_room, event.getRoom());
    		remoteView.setTextViewText(R.id.textViewListViewItem_time, event.getBeginTime()+"-"+event.getEndTime());
    		remoteView.setTextViewText(R.id.textViewListViewItem_course, event.getCourse());
    		
     		break;
    	case TYPE_DAY:
    		
    		//Create a new remoteView with the correct layout
    		remoteView = new RemoteViews( context.getPackageName(), R.layout.listview_item_day);

    		//Fill the remoteView with data
    		remoteView.setTextViewText(R.id.textViewListViewItem_day, event.getWeekday());
    		remoteView.setTextViewText(R.id.textViewListViewItem_date, event.getBeginDate());

    		break;
    		default:
    			// Should never happen
    			remoteView = null;
    			break;
    	}
    	return remoteView;
    }


    @Override
    public RemoteViews getLoadingView() {
            return null;
    }

    @Override
    public boolean hasStableIds() {
            return true;
    }

    @Override
    public void onCreate() {
    }

    @Override
    public void onDataSetChanged() {
    }

    @Override
    public void onDestroy() {
    }

	@Override
	public int getCount() {
		return mData.size();
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public int getViewTypeCount() {
		return TYPE_MAX_COUNT;
	}
	
    public int getItemViewType(int position) {
        return mDaysSet.contains(position) ? TYPE_DAY: TYPE_EVENT;
    }
    


}
